/*
 * @lc app=leetcode.cn id=1178 lang=javascript
 *
 * [1178] 猜字谜
 */

// @lc code=start
/**
 * @param {string[]} words
 * @param {string[]} puzzles
 * @return {number[]}
 */
var findNumOfValidWords = function (words, puzzles) {
  const base = 'a'.charCodeAt();
  const freq = new Map();
  // 利用最多26位二进制保存字母是否出现过abca=111，从右往左算
  for (const word of words) {
    let mask = getBits(word);
    freq.set(mask, (freq.get(mask) || 0) + 1);
  }

  let res = new Array(puzzles.length).fill(0);
  for (const [i, puzzle] of puzzles.entries()) {
    let puzzleBits = getBits(puzzle);
    let firstLetterBits = getBits(puzzle[0]);

    let bits = puzzleBits;
    while (bits > 0) {
      if ((bits & firstLetterBits) !== 0 && freq.has(bits)) {
        res[i] += freq.get(bits);
      }
      bits = (bits - 1) & puzzleBits;
    }
  }

  return res;

  function getBits(word) {
    let mask = 0;
    for (const char of word) {
      mask |= 1 << (char.charCodeAt() - base);
    }
    return mask;
  }
};
// @lc code=end
